import 'dart:io';

import 'package:bitcoin_mine/api/api.dart';
import 'package:bitcoin_mine/model/contract.dart';
import 'package:bitcoin_mine/model/mine_info.dart';
import 'package:bitcoin_mine/model/register_model.dart';
import 'package:decimal/decimal.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:get/get.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../http/http_request.dart';
import '../routes/app_routes.dart';
import '../services/token_service.dart';

class Global {
  static bool isAppLovinMAXInitialized = false;
  static RxBool isLoggedIn = false.obs;
  static Rx<MineInfo?> mineInfo = Rx<MineInfo?>(null);
  static Rx<User?> user = User.empty().obs;
  static RxList<Contract> contracts = <Contract>[].obs;
  static RxDouble totalHashrate = 0.0.obs;
  static String? deviceNo;
  static String? bundleId;
  static String? productVersion;
  static String platformRefer = "47.7.1.88.0"; // 默认值，可通过邀请码对话框更新
  static bool _hasInitApp = false;
  static RxString btcPrice = ''.obs;
  static late TokenService tokenService;
  static RxBool contractUpdating = false.obs;
  static RxList<Good> goods = <Good>[].obs;
  static initApp() async {
    if (Global._hasInitApp) {
      return;
    }
    Global._hasInitApp = true;
    tokenService = Get.find<TokenService>();

    // 从本地存储加载邀请码（如果存在）
    try {
      final prefs = await SharedPreferences.getInstance();
      final savedInvitationCode = prefs.getString('invitation_code');
      if (savedInvitationCode != null && savedInvitationCode.isNotEmpty) {
        platformRefer = savedInvitationCode;
      }
    } catch (e) {
      print('加载邀请码失败: $e');
    }

    // 基础HTTP头
    HttpRequest.instance.addHeader('SDK-Refer', platformRefer);
    HttpRequest.instance.addHeader(
      'Sys-Platform',
      Platform.isAndroid ? 'android' : 'ios',
    );
    HttpRequest.instance.addHeader('SDK-Version', "1.0.0");

    // 设备信息
    if (Platform.isAndroid) {
      AndroidDeviceInfo androidInfo = await DeviceInfoPlugin().androidInfo;
      Global.deviceNo = androidInfo.id;
    } else if (Platform.isIOS) {
      IosDeviceInfo iosInfo = await DeviceInfoPlugin().iosInfo;
      Global.deviceNo = iosInfo.identifierForVendor;
    }
    print('deviceNo: ${Global.deviceNo}');
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    Global.bundleId = packageInfo.packageName;
    Global.productVersion = packageInfo.version;
    // 添加Token认证头
    try {
      if (tokenService.authorizationHeader.isNotEmpty) {
        print(
          'tokenService.authorizationHeader: ${tokenService.authorizationHeader}',
        );
        HttpRequest.instance.addHeader(
          'Authorization',
          tokenService.authorizationHeader,
        );
        Get.offAllNamed(AppRoutes.main);
      } else {
        await _performAutoRegister();
      }
    } catch (ignore) {
      print('初始化失败: $ignore');
      ignore;
    }
  }

  static resetToken(String token) {
    Global.tokenService.clearToken();
    Global.tokenService.accessToken.value = token;
    Global.updateTokenHeader();
    Get.offAllNamed(AppRoutes.main);
  }

  /// 执行自动注册
  static Future<void> _performAutoRegister() async {
    // HttpRequest.instance
    //     .requestCommon(
    //       "POST",
    //       Api.autoRegister,
    //       data: {
    //         "platform": Platform.isIOS ? "0" : "1",
    //         "device_no": Global.deviceNo ?? "",
    //         "bundle_id": Global.bundleId ?? "",
    //         "refer": Global.platformRefer,
    //         "SDK-Refer": Global.platformRefer,
    //         "product_version": Global.productVersion ?? "",
    //       },
    //     )
    //     .then((value) {
    //       print('自动注册成功: ${value}');
    //       if (value != null) {
    //         // setUserInfo(value);
    //       }
    //     });

    HttpRequest.instance.requestNetwork<RegisterModel>(
      Api.autoRegister,
      method: "POST",
      params: {
        "platform": Platform.isIOS ? "0" : "1",
        "device_no": Global.deviceNo ?? "",
        "bundle_id": Global.bundleId ?? "",
        "refer": Global.platformRefer,
        "product_version": Global.productVersion ?? "",
      },
      onSuccess: (value) async {
        print('自动注册成功: $value');
        if (value != null) {
          // 保存用户信息
          setUserInfo(value.user);

          // 保存Token到本地存储
          await tokenService.saveToken(value);

          // 更新HTTP头中的Token
          Global.updateTokenHeader();

          print('自动注册成功');
          Get.offAllNamed(AppRoutes.main);
        }
      },
      onError: (error, stackTrace) {
        print('自动注册失败: $error');
      },
    );
  }

  static setUserInfo(User newUserInfo) {
    user.value = newUserInfo;
    user.refresh();
    isLoggedIn.value = true;
  }

  static logout() {
    isLoggedIn.value = false;
    HttpRequest.instance.addHeader('Authorization', 'Bearer');
  }

  /// 更新HTTP头中的Token
  static updateTokenHeader() {
    try {
      if (tokenService.authorizationHeader.isNotEmpty) {
        HttpRequest.instance.addHeader(
          'Authorization',
          tokenService.authorizationHeader,
        );
      } else {
        // 如果HttpRequest没有removeHeader方法，可以设置为空字符串
        HttpRequest.instance.addHeader('Authorization', 'Bearer');
      }
    } catch (ignore) {
      ignore;
    }
  }

  static getMineInfo() {
    return mineInfo.value;
  }

  static updateMineInfo() async {
    print('东八区时间: ${getBeijingTimeString()}');

    // HttpRequest.instance.requestCommon("GET", Api.bitcoinInfo).then((value) {
    //   print('获取矿机信息成功: $value');
    // });
    await HttpRequest.instance.requestNetwork<MineInfo>(
      Api.bitcoinInfo,
      method: "GET",
      onSuccess: (value) {
        if (value != null) {
          mineInfo.value = value;
          contracts.value = value.contracts.reversed.toList();
          totalHashrate.value = double.parse(
            value.total_hashrate?.toStringAsFixed(2) ?? '0.0',
          );
          btcPrice.value =
              '1${value.exchange_rate.symbol} = ${value.exchange_rate.value}${value.exchange_rate.basePair}';
          value.user.user_info = value.user_info;
          setUserInfo(value.user);
          // print('获取矿机信息成功: ${value.contracts.length}');
          // print('获取矿机信息成功: ${value.total_hashrate ?? 0}');
          // print('获取矿机信息成功: ${value.exchange_rate.toJson()}');
          // print('获取矿机信息成功: ${value.bitcoin_history.toJson()}');
          print('获取矿机信息成功: ${value.free_contract?.toJson()}');
          print('获取矿机信息成功: ${value.total_hashrate?.toString()}');
          print('获取矿机信息成功: ${value.user.toJson()}');
          print('获取矿机信息成功: ${value.user_info?.toJson()}');
          // print('获取矿机信息成功: ${value.goods.map((e) => e.toJson()).toList()}');
          // print('获取矿机信息成功: ${value.goods_map.toJson()}');
          goods.clear();
          goods.addAll(value.goods_map.group1);
          goods.addAll(value.goods_map.group2);
          goods.addAll(value.goods_map.group3);
          goods.addAll(value.goods_map.group4);
          goods.refresh();
          Global.mineInfo.refresh();
        }
      },
      onError: (error, message) {
        print('获取矿机信息失败: $error - $message');
      },
    );
  }

  static updateContract() async {
    if (contractUpdating.value) {
      return;
    }
    contractUpdating.value = true;
    // await HttpRequest.instance.requestCommon("GET", Api.contractList).then((
    //   value,
    // ) {
    //   print('updateContract: $value');
    // });
    await HttpRequest.instance.requestNetwork<List<Contract>>(
      Api.contractList,
      method: "GET",
      onSuccess: (value) {
        if (value != null) {
          contracts.value = value.reversed.toList();
          updateTotalHashrate();
        }

        contractUpdating.value = false;
      },
      onError: (error, stackTrace) {
        contractUpdating.value = false;
      },
    );
  }

  static updateTotalHashrate() {
    Decimal total = Decimal.zero;
    for (final contract in contracts) {
      if (contract.status == 1) {
        total += Decimal.parse(contract.hashrate.toString());
      }
    }
    totalHashrate.value = total.toDouble();
    print("update totalHashrate = ${totalHashrate.value}");
    totalHashrate.refresh();
  }

  /// 获取东八区（UTC+8）当前时间
  /// 返回格式化的 DateTime 对象，表示中国标准时间（CST）
  static DateTime getBeijingTime() {
    // 东八区固定偏移 UTC+8（中国不使用夏令时）
    return DateTime.now().toUtc().add(const Duration(hours: 8));
  }

  /// 获取东八区时间字符串（格式：yyyy-MM-dd HH:mm:ss）
  static String getBeijingTimeString() {
    final beijingTime = getBeijingTime();
    return '${beijingTime.year.toString().padLeft(4, '0')}-'
        '${beijingTime.month.toString().padLeft(2, '0')}-'
        '${beijingTime.day.toString().padLeft(2, '0')} '
        '${beijingTime.hour.toString().padLeft(2, '0')}:'
        '${beijingTime.minute.toString().padLeft(2, '0')}:'
        '${beijingTime.second.toString().padLeft(2, '0')}';
  }

  /// 将 UTC 时间转换为东八区时间
  static DateTime utcToBeijingTime(DateTime utcTime) {
    return utcTime.toUtc().add(const Duration(hours: 8));
  }

  /// 将东八区时间转换为 UTC 时间
  static DateTime beijingTimeToUtc(DateTime beijingTime) {
    return beijingTime.subtract(const Duration(hours: 8)).toUtc();
  }

  /// 计算给定北京时间字符串与当前北京时间的秒差
  /// [beijingTimeStr] 格式：yyyy-MM-dd HH:mm:ss，例如 2025-10-29 15:00:30
  /// 返回：now(Beijing) - input(Beijing) 的秒数，晚于输入则为正，早于输入为负
  static int diffSecondsFromBeijingNow(String beijingTimeStr) {
    try {
      // 快速解析固定格式，避免时区歧义
      // 解释为“北京时间”，再与当前北京时间比较
      final year = int.parse(beijingTimeStr.substring(0, 4));
      final month = int.parse(beijingTimeStr.substring(5, 7));
      final day = int.parse(beijingTimeStr.substring(8, 10));
      final hour = int.parse(beijingTimeStr.substring(11, 13));
      final minute = int.parse(beijingTimeStr.substring(14, 16));
      final second = int.parse(beijingTimeStr.substring(17, 19));

      // 将北京时间点转换为对应 UTC 时刻：UTC = BJ - 8h
      final inputUtc = DateTime.utc(year, month, day, hour - 8, minute, second);

      // 当前北京时间对应的 UTC
      final nowUtc = DateTime.now().toUtc();

      // 秒差（以北京时间基准与 UTC 等价，因为都减去8小时）
      return nowUtc.difference(inputUtc).inSeconds;
    } catch (_) {
      // 解析失败，返回0（也可改为抛异常或返回null）
      return 0;
    }
  }
}
